﻿using DoNet.Common.Encrypt;
using DoNet.Common.Helpers;
using DoNet.Core.DataManager;
using DoNet.Core.Models;
using DoNet.ThirdParty.MiniProfiler;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using SqlSugar;
using System.Linq.Expressions;

namespace DoNet.Core.Extensions
{
    /// <summary>
    /// SqlSugar 启动服务
    /// </summary>
    public static class SqlSugarSetup
    {
        /// <summary>
        /// SqlSugar 上下文初始化
        /// </summary>
        /// <param name="services"></param>
        /// <exception cref="ArgumentNullException"></exception>
        public static void AddSqlSugarSetup(this IServiceCollection services, IConfiguration config)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));

            DbServerProvider dbServerProvider = new DbServerProvider(config);

            // 把多个连接对象注入服务，SqlSugarScope用AddSingleton单例
            services.AddSingleton<ISqlSugarClient>(o =>
            {
                // 连接字符串
                var connectionConfigs = new List<ConnectionConfig>();
                dbServerProvider.allDbConnections.ForEach(m =>
                {
                    ConnectionConfig connectionConfig = new ConnectionConfig()
                    {
                        ConfigId = m.ConnId.ToLower(),
                        ConnectionString = dbServerProvider.isConnectionStringEncrypt ? DEncrypt.Decrypt(m.MasterDB.ConnectionString) : m.MasterDB.ConnectionString,
                        DbType = (DbType)m.MasterDB.DatabaseType,
                        IsAutoCloseConnection = true,
                    };
                    if (m.ReadDB != null)
                    {
                        List<SlaveConnectionConfig> slaveConnectionConfigs = new List<SlaveConnectionConfig>();
                        m.ReadDB.ForEach(r =>
                        {
                            if (r.Enabled)
                            {
                                slaveConnectionConfigs.Add(new SlaveConnectionConfig()
                                {
                                    HitRate = r.HitRate,
                                    ConnectionString = dbServerProvider.isConnectionStringEncrypt ? DEncrypt.Decrypt(r.ConnectionString) : r.ConnectionString
                                });
                            }
                        });
                        connectionConfig.SlaveConnectionConfigs = slaveConnectionConfigs;
                    }
                    connectionConfigs.Add(connectionConfig);
                });
                return new SqlSugarScope(connectionConfigs, db =>
                {
                    connectionConfigs.ForEach(config =>
                    {
                        var dbProvider = db.GetConnectionScope((string)config.ConfigId);

                        dbProvider.Aop.OnError = (ex) =>
                        {
                            var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value));
                            MiniProfilerSetup.AddCurrentCustomTiming("SqlSugar", $"{ex.Message}{Environment.NewLine}{ex.Sql}{pars}{Environment.NewLine}", "Error");
                        };
                        dbProvider.Aop.OnLogExecuted = (sql, p) =>
                        {
                            if (dbServerProvider.sqlAopEnabled)
                            {
                                string logSql = $"{GetParas(p)}【SQL语句】:{GetWholeSql(p, sql)}【耗时】:{dbProvider.Ado.SqlExecutionTime.TotalMilliseconds}ms";
                                MiniProfilerSetup.AddCurrentCustomTiming("SQL:", logSql);
                            }
                        };
                        dbProvider.Aop.DataExecuting = (oldValue, entityInfo) =>
                        {
                            // 新增操作
                            if (entityInfo.OperationType == DataFilterType.InsertByObject)
                            {
                                if (entityInfo.PropertyName == "CreatorTime")
                                    entityInfo.SetValue(DateTime.Now);

                                //if (Appsettings.User != null)
                                //{
                                //    if (entityInfo.PropertyName == "TenantId")
                                //    {
                                //        var tenantId = ((dynamic)entityInfo.EntityValue).TenantId;
                                //        if (tenantId == null || tenantId == 0)
                                //            entityInfo.SetValue(Appsettings.User.TenantId);
                                //    }
                                //    if (entityInfo.PropertyName == "CreatorUserId")
                                //    {
                                //        var createUserId = ((dynamic)entityInfo.EntityValue).CreatorUserId;
                                //        if (createUserId == 0 || createUserId == null)
                                //            entityInfo.SetValue(Appsettings.User?.UserId);
                                //    }
                                //    if (entityInfo.PropertyName == "CreateOrgId")
                                //    {
                                //        var createOrgId = ((dynamic)entityInfo.EntityValue).CreateOrgId;
                                //        if (createOrgId == 0 || createOrgId == null)
                                //            entityInfo.SetValue(Appsettings.User?.CreateOrgId);
                                //    }
                                //}
                            }
                            // 更新操作
                            if (entityInfo.OperationType == DataFilterType.UpdateByObject)
                            {
                                if (entityInfo.PropertyName == "LastModifyTime")
                                    entityInfo.SetValue(DateTime.Now);
                                //if (entityInfo.PropertyName == "LastModifyUserId")
                                //    entityInfo.SetValue(Appsettings.User?.UserId);
                            }
                        };
                    });
                });
            });
            //services.AddScoped(typeof(BaseRepository<>)); // 仓储注册
        }

        private static string GetWholeSql(SugarParameter[] paramArr, string sql)
        {
            foreach (var param in paramArr)
            {
                sql.Replace(param.ParameterName, param.Value.ToString());
            }

            return sql;
        }

        private static string GetParas(SugarParameter[] pars)
        {
            string key = string.Empty;
            if (pars.Length > 0)
            {
                key = "【SQL参数】：";
                foreach (var param in pars)
                {
                    key += $"{param.ParameterName}：{param.Value}\n";
                }
            }
            return key;
        }

        /// <summary>
        /// 配置租户实体过滤器
        /// </summary>
        //public static void SetTenantEntityFilter(SqlSugarScopeProvider db)
        //{
        //    // 获取租户实体数据表集合
        //    var dataEntityTypes = RuntimeHelper.GetAllTypes().Where(u => !u.IsInterface && !u.IsAbstract && u.IsClass && u.BaseType == typeof(TenantEntity));
        //    if (!dataEntityTypes.Any()) return;

        //    var tenantId = Appsettings.User?.TenantId;
        //    if (tenantId == 0 || tenantId == null) return;

        //    foreach (var dataEntityType in dataEntityTypes)
        //    {
        //        Expression<Func<TenantEntity, bool>> dynamicExpression = u => u.TenantId == tenantId;
        //        db.QueryFilter.Add(new TableFilterItem<object>(dataEntityType, dynamicExpression));
        //    }
        //}
    }
}
